<?php
class Backoffice_UsersController extends CC_Controller
{
    /**
     * List and paginate all users
     */
    public function indexAction()
    {
        $dql = $this->_em->createQuery('SELECT u FROM CC\Entity\User u');
        
        $users = new Zend_Paginator(new DoctrineExtensions\Paginate\PaginationAdapter($dql));
        $users->setCurrentPageNumber($this->_getPage())
              ->setItemCountPerPage(20)
              ->setPageRange(10);
        
        $this->view->users = $users;
    }
    
    /**
     * Create a new user
     * 
     * URL: /backoffice/users/create
     */
    public function createAction()
    {
        $form = new Backoffice_Model_FormUser();

        // Check if request is POST
        if($this->getRequest()->isPost())
        {
            // Check if form is valid
            if($form->isValid($this->_request->getPost()))
            {
                // Create new user
                $user = new CC\Entity\User();
                $provider = $this->_em->getReference('CC\Entity\Provider', $form->getValue('provider'));
                
                // Assign the account attributes
                $user->setFirstname($form->getValue('firstname'));
                $user->setInitials($form->getValue('initials'));
                $user->setSurname($form->getValue('surname'));
                $user->setContactNumber($form->getValue('contactNumber'));

                $user->setProvider($provider);
                $user->setUsername($form->getValue('username'));
                $user->setEmail($form->getValue('email'));
                $user->setPassword($form->getValue('password'));
                $user->setSignature($form->getValue('signature'));
                
                // Add each group that was selected to the user
                foreach($form->getValue('groups') as $groupID)
                {
                    $group = $this->_em->getReference('CC\Entity\Group', $groupID);
                    $user->addGroup($group);
                    unset($group);
                }
                
                $this->_em->persist($user);
                $this->_em->flush();
                
                // Display success message and redirect to index action
                $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->account->create, $form->getValue('email')));
                return $this->_helper->redirector('index', 'users', 'backoffice');
            }
            else
            {
                // Assign errors to view
                $this->view->errors = $form->getErrors();
            }
        }

        // Assign form
        $this->view->form = $form;
    }
    
    /**
     * Update the user that was passed via the 'uid' GET parameter
     * 
     * URL: /backoffice/users/update/uid/?
     */
    public function updateAction()
    {
        $isInvalid = false;
        
        // Get the form and make changes to the elements
        // for the update method
        $form = new Backoffice_Model_FormUser();
        $form->setAction("");

        $form->getElement("password")->setRequired(false);
        $form->getElement("confirmPassword")->setRequired(false);
        $form->getElement("submit")->setLabel("Update");

        $request = $this->getRequest();
        
        // Check if uid is set
        if(isset($request->uid))
        {
            /** @var CC\Entity\User */
            $user = $this->_em->getRepository('CC\Entity\User')->findOneById($request->uid);
            
            // Check if user is valid
            if($user !== null)
            {
                // Check if request is post
                if($request->isPost())
                {
                    // Check if form is valid
                    if($form->isValid($this->_request->getPost()))
                    {
                        // Ensure user is valid
                        if($user !== null)
                        {
                            $provider = $this->_em->getReference('CC\Entity\Provider', $form->getValue('provider'));
                            
                            $user->setFirstname($form->getValue('firstname'));
                            $user->setInitials($form->getValue('initials'));
                            $user->setSurname($form->getValue('surname'));
                            $user->setContactNumber($form->getValue('contactNumber'));
            
                            $user->setProvider($provider);
                            $user->setUsername($form->getValue('username'));
                            $user->setEmail($form->getValue('email'));
                            $user->setSignature($form->getValue('signature'));
                            
                            if($form->getValue('password') != '')
                                $user->setPassword($form->getValue('password'));
                            
                            $userGroupIds = $this->_em->getRepository('CC\Entity\User')->getGroupIdArray($user->getId());
        
                            // Remove groups that werent selected 
                            foreach($user->getGroups() as $group)
                            {
                                if(!in_array($group->getId(), $form->getValue('groups')))
                                {
                                    $user->getGroups()->removeElement($group);
                                }
                            }
                            
                            // Add missing group associations
                            foreach($form->getValue('groups') as $groupId)
                            {
                                if(!in_array($groupId, $userGroupIds))
                                {
                                    $group = $this->_em->getRepository('CC\Entity\Group')->findOneById($groupId);
                                    
                                    if($group !== null)
                                        $user->addGroup($group);
                                    
                                    unset($group);
                                }
                            }
                                
                            $this->_em->persist($user);
                            $this->_em->flush();
                            
                            // Display message and redirect to index action
                            $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->account->update, $form->getValue('email')));
                            return $this->_helper->redirector('index', 'users', 'backoffice');
                        }
                        else
                        {
                            // Display error message
                            $this->_helper->messenger('error', Zend_Registry::get('config')->messages->account->invalid);
                            return $this->_helper->redirect('index', 'users', 'backoffice');
                        }
                        
                    }
                    else
                    {
                        // Assign errors to view
                        $this->view->errors = $form->getErrors();
                    }
                }
                else
                {
                    $formData = array(
                        "firstname" => $user->getFirstname(),
                        "initials" => $user->getInitials(),
                        "surname" => $user->getSurname(),
                        "contactNumber" => $user->getContactNumber(),
                        "provider" => $user->getProvider()->getId(),
                        'signature' => $user->getSignature(),
                        'groups' => $this->_em->getRepository('CC\Entity\User')->getGroupIdArray($user->getId()),
                        "username" => $user->getUsername(),
                        "email" => $user->getEmail()
                    );
            
                    $form->populate($formData);
                }
        
                $this->view->form = $form;
            }
            else
            {
                $isInvalid = true;
            }
        }
        else
        {
            $isInvalid = true;
        }
        
        if($isInvalid)
        {
            $this->_helper->messenger('error', Zend_Registry::get('config')->messages->account->invalid);
            return $this->_helper->redirector('index', 'users', 'backoffice');
        }
    }
    
    /**
     * Delete the user with the id passed via the GET param
     * 
     * URL: /backoffice/users/delete/id/?
     */
    public function deleteAction()
    {
        $request = $this->getRequest();
        
        // Check if uid passed
        if(isset($request->uid))
        {
            $user = $this->_em->getRepository('CC\Entity\User')->findOneById($request->uid);
            // Ensure user is valid
            if($user !== null)
            {
                // Grab the email address and remove the entry
                $userEmail = $user->getEmail();
                
                $this->_em->remove($user);
                $this->_em->flush();
                
                // Display success message and redirect to index
                $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->account->delete, $userEmail));
                return $this->_helper->redirector('index', 'users', 'backoffice');
            }
        }
        
        // If it gets here, then there was an error
        // Display the error message and redirect to
        // the index action
        $this->_helper->messenger('success', Zend_Registry::get('config')->messages->account->invalid);
        return $this->_helper->redirector('index', 'users', 'backoffice');
    }
    
    /**
     * Login action
     * 
     * URL: /backoffice/users/login
     */
    public function loginAction()
    {
        $form = new Backoffice_Model_FormLogin();
        
        // Check if request is a POST request
        if($this->getRequest()->isPost())
        {
            // Check if form is valid
            if($form->isValid($this->_request->getPost()))
            {
                // Do authentication
                if($this->_authenticate($this->_em, $this->_request->getPost()))
                {
                    $user = $this->_em->getRepository('CC\Entity\User')
                                 ->findOneByEmail($form->getValue('email'));

                    $this->_em->persist($user);
                    $this->_em->flush();
                    
                    // Generate the flash message and redirect the user
                    $this->_helper->messenger('success',
                            Zend_Registry::get('config')->messages->login->successful
                        );
                        
                    return $this->_redirect("/backoffice");
                }
                else
                {
                    $this->view->error = true;
                }
            }
            else
            {
                $this->view->error = true;
            }
        }

        $this->view->form = $form;
        
        // Change the layout
        $this->_helper->layout->setLayout('login');
    }
    
    /**
     * Logout user
     * 
     * URL: /backoffice/users/logout
     */
    public function logoutAction()
    {
        // Clear the auth to logout
        Zend_Auth::getInstance()->clearIdentity();
        
        // Redirect with message
        $this->_helper->messenger('success', 'You are logged out of your account');
        return $this->_helper->redirector('login', 'users', 'backoffice');
    }
    
    /**
     * Search for a user. Returns a JSON array containing the user details
     * 
     * URL: /backoffice/users/user-search
     */
    public function searchAction()
    {
        /** 
         * @var CC\Service\HelpdeskService 
         */
        $helpdeskService = $this->_serviceLocator->getService('HelpdeskService');
        $this->_helper->viewRenderer->setNoRender();
        $this->_helper->getHelper('layout')->disableLayout();
        
        $users = $helpdeskService->findUser($this->getRequest()->getParam('term'), $this->_helper->userSession()->getId());
        
        echo Zend_Json_Encoder::encode($users);
    }
    
    /**
     * This method handles the actual authentication. It is
     * using a custom adapter that integrates with Doctrine 2
     * 
     * @param Doctrine\ORM\EntityManager $em
     * @param array $data
     * @return boolean
     */
    protected function _authenticate($em, $data)
    {
        $authAdaptor = new CC_Auth_Adapter_Doctrine2();
        $authAdaptor->setEm($em);
        $authAdaptor->setEntityName('CC\Entity\User');
        $authAdaptor->setIdentityColumn("email");
        $authAdaptor->setCredentialColumn("password");

        $authAdaptor->setIdentity($data['email']);
        $authAdaptor->setCredential($data['password'], true);

        /** @var Zend_Auth */
        $auth = Zend_Auth::getInstance();
        $result = $auth->authenticate($authAdaptor);

        if($result->isValid())
        {
            if(isset($data['public']))
            {
                if($data['public'] == true)
                {
                    Zend_Session::rememberMe(1209600);
                    return true;
                }
            }

            Zend_Session::forgetMe();

            return true;
        }
        else
        {
            return false;
        }
    }
}
?>